﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GameLogic.Objects
{
    class Tank : MovingObject
    {
        private Random random;
        //чтобы стрелять через раз
        protected bool Ready { get; set; }
        public Tank(Random rand) : this()
        {
            random = rand;
            //Position = new Rectangle(x, y, Constants.TANK_WIDTH, Constants.TANK_HEIGHT);
        }

        protected Tank()
        {
            HitPoints = Constants.HITS_FOR_TANK;
            Ready = true;
            CurrentDirection = Direction.WEST;
        }

        public override void Move(Map map)
        {
            bool moved = false;
            Ready = !Ready;
          /*  if (random.NextDouble() > Constants.TURN_PROBABILITY)
            {
                ChangeDirection(map);
            }*/
            switch (CurrentDirection)
            {
                case Direction.NORTH:
                    moved = TryMoveNorth(map);
                    break;
                case Direction.EAST:
                    moved = TryMoveEast(map);
                    break;
                case Direction.SOUTH:
                    moved = TryMoveSouth(map);
                    break;
                case Direction.WEST:
                    moved = TryMoveWest(map);
                    break;
            }
            if ((random.NextDouble() <= Constants.SHOT_PROBABILITY || !moved) && Ready)
            {
                Shot();
            }

            if (/*!moved && */random.NextDouble() <= Constants.TURN_PROBABILITY)
            {
                ChangeDirection(map);
            }
        }

        private void ChangeDirection(Map map)
        {
            var nextDirection = (Direction)random.Next(4);//0..3
            if (CurrentDirection == nextDirection)
            {
                CurrentDirection = Direction.EAST;
            }
            else
            {
                CurrentDirection = nextDirection;
            }
        }

        //  /\
        protected bool TryMoveNorth(Map map)
        {
            var body = GetPhysRectangle();
            var positionTo = new Rectangle(body.X, body.Y - Constants.TANK_SPEED, Constants.TANK_HEIGHT, Constants.TANK_WIDTH);
            if (Position.Y >= Constants.TANK_SPEED && !IntersectsWithSmth(positionTo, map))
            {
                Position = new Rectangle(Position.X, Position.Y - Constants.TANK_SPEED, Constants.TANK_HEIGHT, Constants.TANK_WIDTH);
                return true;
            }
            return false;
        }

        //<--
        protected bool TryMoveWest(Map map)
        {
            var body = GetPhysRectangle();
            var positionTo = new Rectangle(body.X - Constants.TANK_SPEED, body.Y, Constants.TANK_WIDTH, Constants.TANK_HEIGHT);
            if (Position.X >= Constants.TANK_SPEED && !IntersectsWithSmth(positionTo, map))
            {
                Position = new Rectangle(Position.X - Constants.TANK_SPEED, Position.Y, Constants.TANK_WIDTH, Constants.TANK_HEIGHT);
                return true;
            }
            return false;
        }

        //-->
        protected bool TryMoveEast(Map map)
        {
            var body = GetPhysRectangle();
            var positionTo = new Rectangle(body.X + Constants.TANK_SPEED, body.Y, Constants.TANK_WIDTH, Constants.TANK_HEIGHT);
            if (Position.X + Constants.TANK_WIDTH + Constants.TANK_SPEED <= map.Width && !IntersectsWithSmth(positionTo, map))
            {
                Position = new Rectangle(Position.X + Constants.TANK_SPEED, Position.Y, Constants.TANK_WIDTH, Constants.TANK_HEIGHT);
                return true;
            }
            return false;
        }

        //  \/
        protected bool TryMoveSouth(Map map)
        {
            var body = GetPhysRectangle();
            var positionTo = new Rectangle(body.X, body.Y + Constants.TANK_SPEED, Constants.TANK_HEIGHT, Constants.TANK_WIDTH);
            if (Position.Y + Constants.TANK_WIDTH + Constants.TANK_SPEED <= map.Height && !IntersectsWithSmth(positionTo, map))
            {
                Position = new Rectangle(Position.X, Position.Y + Constants.TANK_SPEED, Constants.TANK_HEIGHT, Constants.TANK_WIDTH);
                return true;
            }
            return false;
        }

        public override void Draw(Graphics graphics)
        {
            Rectangle place = GetPhysRectangle();
            Image image = GetCurrentImage();
            DrawByPicture(graphics, image, place);
            //graphics.DrawRectangle(new Pen(Brushes.Black), Position.X, Position.Y, 2, 2);
            //graphics.DrawRectangle(new Pen(Brushes.Black), place);
        }

        public override Rectangle GetPhysRectangle()
        {
            switch (CurrentDirection)
            {
                case Direction.NORTH:
                case Direction.SOUTH:
                    return new Rectangle(Position.X - Constants.CELL_SIZE / 4, Position.Y - Constants.CELL_SIZE / 2, Constants.TANK_HEIGHT, Constants.TANK_WIDTH);
                case Direction.EAST:
                case Direction.WEST:
                    return new Rectangle(Position.X - Constants.CELL_SIZE / 2, Position.Y - Constants.CELL_SIZE / 4, Constants.TANK_WIDTH, Constants.TANK_HEIGHT);
            }
            throw new Exception("Tank.GetPhysRectangle: CurrentDirection = " + CurrentDirection.ToString());
        }

        public virtual void Shot()
        {
            if (Ready)
            {
                var position = GetBulletRectangle();
                Bullet bullet = new Bullet(this)
                {
                    CurrentDirection = this.CurrentDirection,
                    Position = position,
                };

                BulletCreationEventArgs args = new BulletCreationEventArgs()
                {
                    Bullet = bullet,
                    IsPlayerBullet = false,
                };
                if (OnShot != null)
                {
                    OnShot(this, args);
                }
            }
        }

        public override Image GetCurrentImage()
        {
            switch (CurrentDirection)
            {
                case Direction.NORTH:
                    return PictureManager.GetImage(ImageKind.TANK_NORTH);
                case Direction.EAST:
                    return PictureManager.GetImage(ImageKind.TANK_EAST);
                case Direction.SOUTH:
                    return PictureManager.GetImage(ImageKind.TANK_SOUTH);
                case Direction.WEST:
                default:
                    return PictureManager.GetImage(ImageKind.TANK_WEST);
            }
        }

        public virtual Rectangle GetBulletRectangle()
        {
            Rectangle result;
            Size size = new Size(Constants.BULLET_SIZE, Constants.BULLET_SIZE);
            Point point;
            switch (CurrentDirection)
            {
                case Direction.NORTH:
                    point = new Point(Position.X - 30, Position.Y - Constants.BULLET_SIZE - Constants.TANK_WIDTH / 2);
                    result = new Rectangle(point, size);
                    return result;
                case Direction.EAST:
                    point = new Point(Position.X + Constants.BULLET_SIZE / 2 + Constants.TANK_WIDTH / 2, Position.Y - 30);
                    result = new Rectangle(point, size);
                    return result;
                case Direction.SOUTH:
                    point = new Point(Position.X - 30, Position.Y + Constants.BULLET_SIZE / 2 + Constants.TANK_WIDTH / 2);
                    result = new Rectangle(point, size);
                    return result;
                case Direction.WEST:
                    point = new Point(Position.X - Constants.BULLET_SIZE*5 - Constants.TANK_WIDTH / 2, Position.Y - 30);
                    result = new Rectangle(point, size);
                    return result;
            }
            throw new Exception("Tank.GetBulletRectangle");
        }

        public virtual event EventHandler<BulletCreationEventArgs> OnShot;
    }
}